using System;
using System.Collections.Generic;
using roster.Domain;

namespace roster.UI
{
    public class RaidController : IRaidController
    {
        private readonly IRaidView m_RaidView;
        private ILootList m_LootList;

        public event Action<IEnumerable<IPlayer>> EndRaid;
        public event Action<IEnumerable<IPlayer>> AddPlayer;

        public RaidController(IRaidView raidView)
        {
            m_RaidView = raidView;
            m_RaidView.UpdateRaid += m_RaidView_UpdateRaid;
            m_RaidView.CancelRaid += m_RaidView_CancelRaid;
            m_RaidView.MoveUp += m_RaidView_MoveUp;
            m_RaidView.MoveDown += m_RaidView_MoveDown;
            m_RaidView.Suicide += m_RaidView_Suicide;
            m_RaidView.AddPlayer += m_RaidView_AddPlayer;
            m_RaidView.TokenSelected += m_RaidView_TokenSelected;
            m_RaidView.RemovePlayer += m_RaidView_RemovePlayer;

            var tokens = new List<ILootToken> {new FallenChampion(), new FallenDefender(), new FallenHero()};
            m_RaidView.SetTokens(tokens);
        }

        private void m_RaidView_RemovePlayer(IEnumerable<IPlayer> players)
        {
            players.ForEach(m_LootList.RemovePlayer);
            UpdateRaidView();
        }

        private void m_RaidView_TokenSelected(ILootToken token)
        {
            m_RaidView.SelectPlayers(token.GetEligiblePlayers(m_LootList));
        }

        private void m_RaidView_CancelRaid()
        {
            EndRaid(new IPlayer[] {});
        }

        void m_RaidView_UpdateRaid()
        {
            EndRaid(m_LootList);
        }

        public void StartRaid(IEnumerable<IPlayer> players)
        {
            m_LootList = new LootList(players);
            m_RaidView.Show();
            UpdateRaidView();
        }

        public void SetTitle(string title)
        {
            m_RaidView.SetTitle(title);
        }

        private void m_RaidView_Suicide(IPlayer player)
        {
            m_LootList.Suicide(player);
            UpdateRaidView(player);
        }

        private void m_RaidView_MoveDown(IPlayer player)
        {
            m_LootList.MovePlayerDown(player);
            UpdateRaidView(player);
        }

        private void m_RaidView_MoveUp(IPlayer player)
        {
            m_LootList.MovePlayerUp(player);
            UpdateRaidView(player);
        }

        private void UpdateRaidView(IPlayer player)
        {
            UpdateRaidView();
            m_RaidView.SelectPlayer(player);
        }

        private void UpdateRaidView()
        {
            m_RaidView.UpdateView(m_LootList);
        }

        private void m_RaidView_AddPlayer()
        {
            AddPlayer(m_LootList);
        }

        public void InsertPlayers(IEnumerable<IPlayer> players)
        {
            m_LootList.AddPlayers(players);
            UpdateRaidView();
        }
    }
}